package com.lz.sports.vm.config

import android.text.Editable
import android.text.TextUtils
import android.widget.RadioGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lz.library.base.BaseModel
import com.lz.library.base.BaseViewModel
import com.lz.library.base.SingleLiveData
import com.lz.library.extension.showToast
import com.lz.sports.LogUtils
import com.lz.sports.R
import com.lz.sports.bean.DeviceInfo
import com.lz.sports.core.*
import com.lz.sports.db.DeviceDatabase
import com.lz.ub.UBCCallback
import com.lz.ub.UBCDevice
import com.lz.ub.UBCManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext

//设备管理编辑
class DeviceEditViewModel : BaseViewModel<BaseModel>(), UBCCallback {

    companion object {
        //断开清空连接延时
        private const val CLEAR_DELAY = 1000L
    }

    //设备列表
    private val deviceList =  ArrayList<DeviceInfo>()
    //当前设备索引
    private var position: Int = 0
    //延时操作
    val delayEvent = SingleLiveData<Int>()
    //是否有上和下一个
    val hasPre = MutableLiveData(false)
    val hasNext = MutableLiveData(false)
    //当前设备
    val deviceInfo = MutableLiveData<DeviceInfo>()
    //是否为辅助设备
    private var isAssist: Boolean = false
    //设备名
    val deviceName = MutableLiveData("")
    //设备别名
    val deviceAlias = MutableLiveData("")
    //保存
    val saveEnabled = MutableLiveData(true)

    //0 离线, 1 在线
//    val lineState = MutableLiveData(0)

    override fun onCreate(owner: LifecycleOwner) {
        UBCManager.get().addUBCCallback(this)
        delayEvent.setValue(2)
    }

    override fun onCleared() {
        super.onCleared()
        deviceInfo.value?.changeLine(false)
        UBCManager.get().removeUBCCallback(this)
        UBCManager.get().clear()
    }

    fun initDeviceInfoList(deviceList: ArrayList<DeviceInfo>, position: Int) {
        this.deviceList.clear()
        this.deviceList.addAll(deviceList)
        this.position = position
        hasPre.value = position > 0
        hasNext.value = position < deviceList.size - 1
        initDevice(deviceList[position])
    }

    fun afterNameChanged(editable: Editable) {
        saveEnabled.value = !TextUtils.isEmpty(editable)
    }

    fun onTypeCheckedChanged(group: RadioGroup, checkedId: Int) {
        isAssist = checkedId == R.id.rb_assist
    }

    private fun initDevice(deviceInfo: DeviceInfo) {
        this.deviceInfo.value = deviceInfo
        isAssist = deviceInfo.isAssist()
        deviceName.value = deviceInfo.name
        deviceAlias.value = deviceInfo.alias
    }

    fun save() {
        if (deviceInfo.value == null) return
        val device = deviceInfo.value!!
        device.name = deviceName.value!!.trim()
        device.alias = deviceAlias.value!!.trim()
        //修改前的设备组ID
        val preGroupId = device.groupId
        val modify = device.changeAssist(isAssist)
        launch {
            withContext(Dispatchers.Default) {
                if (DeviceInfo.hasGroup(preGroupId) && modify) {
                    //已绑定过组的设备变了
                    DeviceDatabase.get().updateDeviceInfoAndGroup(device, preGroupId)
                } else {
                    DeviceDatabase.get().updateDeviceInfo(device)
                }
            }
            R.string.saveSuccess.showToast()
            this@DeviceEditViewModel.deviceInfo.value = device
            LiveEventBus.get("DeviceInfo_Edit", DeviceInfo::class.java).post(device)
        }
    }

    fun connect() {
        if (deviceInfo.value == null) return
        val device = deviceInfo.value!!
        if (device.isAssist()) {
            UBCManager.get().addDevice(device.mac, ASSIST_W_NUM, ASSIST_R_NUM, false)
        } else {
            UBCManager.get().addDevice(device.mac, DEVICE_W_NUM, DEVICE_R_NUM, false)
        }
        launch {
            updateDialogLoading(true)
            delay(500)
            UBCManager.get().connect()
            delay(1000)
            updateDialogLoading(false)
        }
    }

    fun send() {
        if (deviceInfo.value == null) return
        UBCManager.get().pushHexCommand(deviceInfo.value!!.mac, COMMAND_SOUND)
    }

    fun delete() {
        if (deviceInfo.value == null) return
        val device = deviceInfo.value!!
        LogUtils.i("delete deviceGroupId = ${device.groupId}")
        launch {
            withContext(Dispatchers.Default) {
                DeviceDatabase.get().deleteDeviceInfo(device)
            }
            R.string.device_delete_s.showToast()
            deviceList.removeAt(position)
            LiveEventBus.get("DeviceInfo_Delete", DeviceInfo::class.java).post(device)
            if (deviceList.isNotEmpty()) {
                if (position > deviceList.size - 1) position = deviceList.size - 1
                hasPre.value = position > 0
                hasNext.value = position < deviceList.size - 1
                initDevice(deviceList[position])
            } else {
                finish()
            }
        }
    }

    fun pre() {
        if (position > 0) {
            launch {
                deviceInfo.value?.changeLine(false)
                updateDialogLoading(true)
                UBCManager.get().clear()
                delay(CLEAR_DELAY)
                updateDialogLoading(false)

                hasPre.value = --position > 0
                hasNext.value = true
                initDevice(deviceList[position])
            }
        }
    }

    fun next() {
        if (position < deviceList.size - 1) {
            launch {
                deviceInfo.value?.changeLine(false)
                updateDialogLoading(true)
                UBCManager.get().clear()
                delay(CLEAR_DELAY)
                updateDialogLoading(false)

                hasNext.value = ++position < deviceList.size - 1
                hasPre.value = true
                initDevice(deviceList[position])
            }
        }
    }

    override fun onReadHex(device: UBCDevice, bytes: ByteArray, start: Int, size: Int, isAssist: Boolean) = Unit

    override fun onRead(device: UBCDevice, data: String, isAssist: Boolean) = Unit

    override fun onConnected(device: UBCDevice, isAssist: Boolean) {
        if (deviceInfo.value == null) return
        if (device.mac == deviceInfo.value!!.mac) {
            deviceInfo.value!!.changeLine(true)
        }
    }

    override fun onDisconnected(device: UBCDevice, isAssist: Boolean) {
        if (deviceInfo.value == null) return
        if (device.mac == deviceInfo.value!!.mac) {
            deviceInfo.value!!.changeLine(false)
        }
    }
}